import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
import { Messager, createRandomId } from '@/utils'
import settings from '@/config'

//初始化跨源通信实例
const messager = new Messager(settings.decorateOrigin)
Vue.use(Vuex)

//利用webpack里的require.context动态引入
const modulesFiles = require.context('./modules', true, /\.js$/)
//.keys方法可以获取./modules文件夹目录里面所有的文件路径 入./index.js
let modules = modulesFiles.keys().reduce((modules, modulePath) => {
  //通过正则获取路径里面除去./和后缀的值 将该值作为key
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
  //  console.log(modulesFiles(modulePath));这个方法返回一个reuqire函数 可以读取文件里面的内容
  //以moduleName为key 文件里面的内容为value 执行
  modules[moduleName] = modulesFiles(modulePath).default
  return modules
}, {})

//页面初始化数据
const emptyPageData = {
  id: '',
  name: '页面标题',
  shareDesc: '',//微信分享文案
  shareImage: '',//微信分享图片
  backgroundColor: '',//页面的背景颜色
  backgroundImage:'',//背景图片
  backgroundPosition: 'top',//页面背景位置
  cover: '',
  componentList: []
}

const store = new Vuex.Store({
  state: {
    //当前组件是否在拖动
    dragActive: false,
    //正在拖动的组件
    dragComponent: {},
    //确保数据没有任何关联
    pageData: JSON.parse(JSON.stringify(emptyPageData)),
    //iframe容器的高度
    previewHeight: 0,
    //h5页面各个容器的高度数据
    componentsTopList: [],
    //拖动组件要添加的位置 用于判断组件预添加是否存在
    addComponentIndex: null,
    //当前选中组件的id
    activeComponentId: null,
    //判断右边tab的内容选定的是页面还是组件 1-页面 2-组件
    setType: 1,
    //控制公共上传弹窗是否弹出的属性
    dialogImageVisible:false,
    //公共上传图片成功时候的回调事件
    upLoadImgSuccess:null,
    wxParams: JSON.stringify({isLogin: true}) // h5页面参数
  },
  mutations: {
    //点击新增重置页面
    SET_INIT_PAGE_DATA(state) {
      state.pageData = JSON.parse(JSON.stringify(emptyPageData))
    },
    //修改组件拖动状态
    SET_DRAG_STATE(state, value) {
      state.dragActive = value
    },
    //修改当前正在拖动的组件
    SET_DRAG_COMPONENT(state, value) {
      state.dragComponent = value
    },
    //页面更新方法
    UPDATE_COMPONENT(state, { data }) {
      state.pageData = data || {}
      console.log(state.pageData,'页面更新方法11');
    },
    //向H5页面发送修改后的数据
    VIEW_UPDATE(state,disabledRestHeight = false) {
      console.log(state.pageData,'upupupup');
      //调用跨元通信的方法 把标识和内容传过去
      messager.emit('pageChange', {
        disabledRestHeight,
        value: state.pageData
      })
    },
    //获取H5高度并且更新
    UPDATE_PAGE_HEIGHT(state, { height, list }) {
      // console.log('更新了页面高度',height);
      state.previewHeight = height
      // console.log( 'state',state.previewHeight)
      state.componentsTopList = list
    },
    //跨源通信修改拖动组件要添加的位置
    SET_DRAG_INDEX(state, value) {
      state.addComponentIndex = value
      console.log('setqidong');
    },
    //向H5发送组件预添加的索引
    VIEW_DRAG_PREVIEW(state, index) {
      messager.emit('setPreview', index)
    },
    //修改选中组件的id
    SET_ACTIVE_ID(state, value) {
      state.activeComponentId = value
    },
    //向H5页面发送指定选中的组件
    VIEW_SET_ACTIVE(state, id) {
      messager.emit('setActive', id)
    },
    //修改页面设置或者组件设置
    SET_SETTYPE(state, value) {
      state.setType = value
    },
    //页面新增组件的方法
    ADD_COMPONENT(state, { index, data }) {
      console.log('add', index, data);
      const component = JSON.parse(JSON.stringify(data))
      //生成随机数
      const id = component.data.component + '-' + createRandomId()
      //添加在数据上
      component.id = id
      //插入组件数据
      state.pageData.componentList.splice(index, 0, component)
      //设置新加入的组件状态为选中 调用方法
      this.commit('SET_ACTIVE_ID', id)
      //更新H5选中组件效果
      this.commit('VIEW_SET_ACTIVE', id)
      //将页面修改为组件设置
      this.commit('SET_SETTYPE', 2)
      //重置拖动组件添加的位置
      this.commit('SET_DRAG_INDEX', null)

    },
    //页面删除组件的方法
    DELETE_COMPONENT() {
      messager.emit('deletePreview')
    },
    //页面编辑组件的方法
    EDIT_COMPONENT(state,{id,data}) { 
        //找到需要修改的组件数据
       const component= state.pageData.componentList.find(item=> item.id === id)
       //组件存在 给data重新赋值
       if (component) {
         component.data=data
       }
    },
    //修改页面设置页面的属性配置
    SET_PAGE_CONFIG(state, config) {
      //拿到对象的枚举值(key) 遍历
      Object.keys(config).forEach(item =>
        state.pageData[item] = config[item]
      )
      //修改完数据后 同步给crs
      this.commit('VIEW_UPDATE',true)
    },
    //修改上传图片公共弹窗是否显示
    SET_UPIMAGE_VISIBLE(state,value){
      state.dialogImageVisible=value
    },
    //修改公共上传图片成功的回调事件
    SET_UPIMAGE_FUC(state,value){
      state.upLoadImgSuccess=value
    }
  },
  actions: {
    //跨源通信对象H5数据的监听
    initMessage({ commit }) {
      // console.log('嗲用了init');
      //接收容器的高度
      messager.on('pageHeightChange', data => {
        let height = data.height
        //每个容器的高度
        const list = data.componentsTopList
        // console.log('进来了imitmessage',data.height);
        commit('UPDATE_PAGE_HEIGHT', { height, list })
      })
      //监听crs页面选中项id的变化
      messager.on('setActive', id => {
        //选定组件
        commit('SET_ACTIVE_ID', id)
        //修改settype 即选定组件的的时候右侧切换为组件设置
        commit('SET_SETTYPE', 2)
      })
      //监听H5预览页面数据变化
      messager.on('pageChange',data=>{
        commit('UPDATE_COMPONENT',{data})
      })
    },
    pageChange({ commit }, changeValue) {
      //定义选择change方法的tab
      const commitObj = {
        add: 'ADD_COMPONENT',
        delete: 'DELETE_COMPONENT',
        edit: 'EDIT_COMPONENT'
      }
      commitObj[changeValue.type] && commit(commitObj[changeValue.type], changeValue)
      //向H5页面发送更新后的数据
      commit('VIEW_UPDATE')
    }
  },
  getters,
  modules
})

Vue.store = store

export default store